package cn.flying.cloud.base.core.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.UUID;

import org.slf4j.MDC;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import cn.flying.cloud.base.common.constants.Constants;
import cn.flying.cloud.base.common.utils.Ft;
import cn.flying.cloud.base.common.utils.lang.StringUtil;

/**
 * 拦截器 设置上下文
 *
 * @author: admin
 * @date: 2023年02月20日 18:31
 * @version: 1.0
 */
public class RequestContextInterceptor implements HandlerInterceptor {
    /**
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  chosen handler to execute, for type and/or instance evaluation
     * @return {@code true} if the execution chain should proceed with the
     * next interceptor or the handler itself. Else, DispatcherServlet assumes
     * that this interceptor has already dealt with the response itself.
     * @throws Exception in case of errors
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 租户Id
        String tenantId = request.getHeader(Constants.TENANT_ID);
        if (StringUtil.isNotBlank(tenantId)) {
            Ft.ThreadLocal.set(Constants.TENANT_ID, tenantId);
        }
        // 用户Id
        String userId = request.getHeader(Constants.USER_ID);
        if (StringUtil.isNotBlank(userId)) {
            Ft.ThreadLocal.set(Constants.USER_ID, userId);
        }
        // 用户名
        String userName = request.getHeader(Constants.USER_NAME);
        if (StringUtil.isNotBlank(userName)) {
            Ft.ThreadLocal.set(Constants.USER_NAME, userName);
        }
        // 请求链路Id
        String traceId = request.getHeader(Constants.TRAC_ID);
        if (StringUtil.isBlank(traceId)) {
            traceId = UUID.randomUUID().toString().replaceAll("-", "");
        }
        MDC.put(Constants.TRAC_ID, traceId);
        // 请求者Id
        String requestId = request.getHeader(Constants.REQUEST_ID);
        if (StringUtil.isNotBlank(requestId)) {
            Ft.ThreadLocal.set(Constants.REQUEST_ID, requestId);
        }
        // 环境
        String envId = request.getHeader(Constants.ENV_ID);
        if (StringUtil.isNotBlank(envId)) {
            Ft.ThreadLocal.set(Constants.ENV_ID, envId);
        }
        return true;
    }

    /**
     * @param request  current HTTP request
     * @param response current HTTP response
     * @param handler  the handler (or {@link HandlerMethod}) that started asynchronous
     *                 execution, for type and/or instance examination
     * @param ex       any exception thrown on handler execution, if any; this does not
     *                 include exceptions that have been handled through an exception resolver
     * @throws Exception in case of errors
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        Ft.ThreadLocal.remove(Constants.TENANT_ID);
        Ft.ThreadLocal.remove(Constants.USER_ID);
        Ft.ThreadLocal.remove(Constants.USER_NAME);

        MDC.remove(Constants.TRAC_ID);

    }
}
